<template>
  <div class="notification-template">
    <!-- 搜索和操作栏 -->
    <div class="operation-bar">
      <div class="left">
        <el-input
          v-model="searchQuery"
          placeholder="搜索模板名称"
          clearable
          @clear="handleSearch"
          @keyup.enter="handleSearch"
          style="width: 200px"
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
        <el-select
          v-model="categoryId"
          placeholder="选择分类"
          clearable
          @change="handleSearch"
          style="width: 150px; margin-left: 16px"
        >
          <el-option
            v-for="item in categories"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </div>
      <div class="right">
        <el-button-group>
          <el-button type="primary" @click="handleImport">
            <el-icon><Upload /></el-icon>导入
          </el-button>
          <el-button type="primary" @click="handleExport">
            <el-icon><Download /></el-icon>导出
          </el-button>
        </el-button-group>
        <el-button type="primary" @click="handleCreate" style="margin-left: 16px">
          <el-icon><Plus /></el-icon>新建模板
        </el-button>
      </div>
    </div>

    <!-- 模板列表 -->
    <el-table
      :data="templateList"
      border
      v-loading="loading"
      style="width: 100%; margin-top: 16px"
    >
      <el-table-column prop="name" label="模板名称" min-width="150" />
      <el-table-column prop="categoryName" label="分类" width="120" />
      <el-table-column prop="type" label="消息类型" width="120">
        <template #default="scope">
          <el-tag :type="getMessageTypeTag(scope.row.type)">
            {{ getMessageTypeLabel(scope.row.type) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="channels" label="通知渠道" min-width="200">
        <template #default="scope">
          <el-tag
            v-for="channel in scope.row.channels"
            :key="channel"
            class="channel-tag"
            :type="getChannelTagType(channel)"
          >
            {{ getChannelLabel(channel) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="variables" label="变量" min-width="200">
        <template #default="scope">
          <el-tag
            v-for="variable in scope.row.variables"
            :key="variable.name"
            class="variable-tag"
            type="info"
          >
            {{ variable.name }}
            <el-tooltip
              :content="variable.description"
              placement="top"
              :show-after="500"
            >
              <el-icon class="info-icon"><InfoFilled /></el-icon>
            </el-tooltip>
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="updateTime" label="更新时间" width="180" />
      <el-table-column label="操作" width="250" fixed="right">
        <template #default="scope">
          <el-button
            type="primary"
            link
            @click="handleEdit(scope.row)"
          >编辑</el-button>
          <el-button
            type="primary"
            link
            @click="handlePreview(scope.row)"
          >预览</el-button>
          <el-button
            type="primary"
            link
            @click="handleCopy(scope.row)"
          >复制</el-button>
          <el-button
            type="danger"
            link
            @click="handleDelete(scope.row)"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination-container">
      <el-pagination
        v-model:current-page="pageNum"
        v-model:page-size="pageSize"
        :total="total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 模板表单对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogType === 'create' ? '新建模板' : '编辑模板'"
      width="800px"
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="模板名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入模板名称" />
        </el-form-item>
        <el-form-item label="所属分类" prop="categoryId">
          <el-select
            v-model="form.categoryId"
            placeholder="请选择分类"
            style="width: 100%"
          >
            <el-option
              v-for="item in categories"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="消息类型" prop="type">
          <el-select
            v-model="form.type"
            placeholder="请选择消息类型"
            style="width: 100%"
          >
            <el-option
              v-for="type in messageTypes"
              :key="type.value"
              :label="type.label"
              :value="type.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="通知渠道" prop="channels">
          <el-checkbox-group v-model="form.channels">
            <el-checkbox label="inApp">站内消息</el-checkbox>
            <el-checkbox label="email">邮件通知</el-checkbox>
            <el-checkbox label="sms">短信通知</el-checkbox>
            <el-checkbox label="wecom">企业微信</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="模板内容" prop="content">
          <div class="template-editor">
            <div class="editor-toolbar">
              <el-button-group>
                <el-button
                  v-for="variable in form.variables"
                  :key="variable.name"
                  @click="insertVariable(variable)"
                >
                  {{ variable.name }}
                </el-button>
              </el-button-group>
            </div>
            <el-input
              v-model="form.content"
              type="textarea"
              :rows="6"
              placeholder="请输入模板内容，支持变量：{{变量名}}"
            />
          </div>
        </el-form-item>
        <el-form-item label="变量配置">
          <div class="variables-editor">
            <div
              v-for="(variable, index) in form.variables"
              :key="index"
              class="variable-item"
            >
              <el-input
                v-model="variable.name"
                placeholder="变量名"
                style="width: 150px"
              />
              <el-input
                v-model="variable.description"
                placeholder="变量说明"
                style="width: 200px"
              />
              <el-select
                v-model="variable.type"
                placeholder="变量类型"
                style="width: 120px"
              >
                <el-option label="文本" value="text" />
                <el-option label="数字" value="number" />
                <el-option label="日期" value="date" />
                <el-option label="时间" value="time" />
                <el-option label="日期时间" value="datetime" />
              </el-select>
              <el-button
                type="danger"
                link
                @click="removeVariable(index)"
              >删除</el-button>
            </div>
            <el-button
              type="primary"
              link
              @click="addVariable"
            >
              <el-icon><Plus /></el-icon>添加变量
            </el-button>
          </div>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="form.remark"
            type="textarea"
            :rows="3"
            placeholder="请输入备注信息"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm" :loading="submitting">
          确定
        </el-button>
      </template>
    </el-dialog>

    <!-- 预览对话框 -->
    <el-dialog
      v-model="previewVisible"
      title="模板预览"
      width="600px"
    >
      <div class="preview-content">
        <div class="preview-header">
          <h3>{{ previewData.name }}</h3>
          <div class="preview-channels">
            <el-tag
              v-for="channel in previewData.channels"
              :key="channel"
              :type="getChannelTagType(channel)"
              class="channel-tag"
            >
              {{ getChannelLabel(channel) }}
            </el-tag>
          </div>
        </div>
        <div class="preview-body">
          <div
            v-for="(variable, index) in previewData.variables"
            :key="index"
            class="preview-variable"
          >
            <span class="variable-label">{{ variable.name }}：</span>
            <el-input
              v-model="previewValues[variable.name]"
              :placeholder="variable.description"
              @input="updatePreview"
            />
          </div>
          <div class="preview-result">
            <div class="result-label">预览结果：</div>
            <div class="result-content" v-html="previewResult"></div>
          </div>
        </div>
      </div>
    </el-dialog>

    <!-- 导入对话框 -->
    <el-dialog
      v-model="importVisible"
      title="导入模板"
      width="400px"
    >
      <el-upload
        class="template-upload"
        drag
        action="#"
        :auto-upload="false"
        :on-change="handleFileChange"
        :limit="1"
        accept=".xlsx,.xls,.csv"
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            支持 .xlsx、.xls、.csv 格式，文件大小不超过 10MB
          </div>
        </template>
      </el-upload>
      <template #footer>
        <el-button @click="importVisible = false">取消</el-button>
        <el-button
          type="primary"
          @click="confirmImport"
          :loading="importing"
          :disabled="!importFile"
        >
          开始导入
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Search,
  Plus,
  Upload,
  Download,
  InfoFilled,
  UploadFilled
} from '@element-plus/icons-vue'
import {
  getMessageTemplateList,
  createMessageTemplate,
  updateMessageTemplate,
  deleteMessageTemplate,
  getMessageTypes,
  getAllMessageCategories,
  importMessageTemplates,
  exportMessageTemplates
} from '@/api/message'

// 数据加载状态
const loading = ref(false)
const submitting = ref(false)
const importing = ref(false)

// 分页数据
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)

// 搜索条件
const searchQuery = ref('')
const categoryId = ref('')

// 列表数据
const templateList = ref([])
const messageTypes = ref([])
const categories = ref([])

// 对话框显示状态
const dialogVisible = ref(false)
const previewVisible = ref(false)
const importVisible = ref(false)
const dialogType = ref('create')

// 表单引用
const formRef = ref(null)

// 表单数据
const form = reactive({
  id: '',
  name: '',
  categoryId: '',
  type: '',
  channels: [],
  content: '',
  variables: [],
  remark: ''
})

// 预览数据
const previewData = ref({})
const previewValues = reactive({})
const previewResult = ref('')

// 导入文件
const importFile = ref(null)

// 表单验证规则
const rules = {
  name: [{ required: true, message: '请输入模板名称', trigger: 'blur' }],
  categoryId: [{ required: true, message: '请选择所属分类', trigger: 'change' }],
  type: [{ required: true, message: '请选择消息类型', trigger: 'change' }],
  channels: [{ required: true, message: '请选择通知渠道', trigger: 'change' }],
  content: [{ required: true, message: '请输入模板内容', trigger: 'blur' }]
}

// 初始化数据
onMounted(async () => {
  await Promise.all([
    fetchTemplateList(),
    fetchMessageTypes(),
    fetchCategories()
  ])
})

// 获取模板列表
const fetchTemplateList = async () => {
  loading.value = true
  try {
    const params = {
      pageNum: pageNum.value,
      pageSize: pageSize.value,
      query: searchQuery.value,
      categoryId: categoryId.value
    }
    const res = await getMessageTemplateList(params)
    templateList.value = res.data.list
    total.value = res.data.total
  } catch (error) {
    console.error('获取模板列表失败:', error)
    ElMessage.error('获取模板列表失败')
  } finally {
    loading.value = false
  }
}

// 获取消息类型
const fetchMessageTypes = async () => {
  try {
    const res = await getMessageTypes()
    messageTypes.value = res.data
  } catch (error) {
    console.error('获取消息类型失败:', error)
    ElMessage.error('获取消息类型失败')
  }
}

// 获取分类列表
const fetchCategories = async () => {
  try {
    const res = await getAllMessageCategories()
    categories.value = res.data
  } catch (error) {
    console.error('获取分类列表失败:', error)
    ElMessage.error('获取分类列表失败')
  }
}

// 搜索处理
const handleSearch = () => {
  pageNum.value = 1
  fetchTemplateList()
}

// 分页处理
const handleSizeChange = (val) => {
  pageSize.value = val
  fetchTemplateList()
}

const handleCurrentChange = (val) => {
  pageNum.value = val
  fetchTemplateList()
}

// 新建模板
const handleCreate = () => {
  dialogType.value = 'create'
  Object.assign(form, {
    id: '',
    name: '',
    categoryId: '',
    type: '',
    channels: [],
    content: '',
    variables: [],
    remark: ''
  })
  dialogVisible.value = true
}

// 编辑模板
const handleEdit = (row) => {
  dialogType.value = 'edit'
  Object.assign(form, row)
  dialogVisible.value = true
}

// 复制模板
const handleCopy = (row) => {
  dialogType.value = 'create'
  const { id, ...rest } = row
  Object.assign(form, {
    ...rest,
    name: `${rest.name} - 副本`
  })
  dialogVisible.value = true
}

// 删除模板
const handleDelete = (row) => {
  ElMessageBox.confirm('确定要删除该模板吗？', '提示', {
    type: 'warning'
  }).then(async () => {
    try {
      await deleteMessageTemplate(row.id)
      ElMessage.success('删除成功')
      fetchTemplateList()
    } catch (error) {
      console.error('删除失败:', error)
      ElMessage.error('删除失败')
    }
  })
}

// 预览模板
const handlePreview = (row) => {
  previewData.value = row
  previewValues.value = {}
  row.variables.forEach(variable => {
    previewValues.value[variable.name] = ''
  })
  updatePreview()
  previewVisible.value = true
}

// 更新预览
const updatePreview = () => {
  let result = previewData.value.content
  Object.entries(previewValues.value).forEach(([key, value]) => {
    const regex = new RegExp(`{{${key}}}`, 'g')
    result = result.replace(regex, value || `{{${key}}}`)
  })
  previewResult.value = result
}

// 添加变量
const addVariable = () => {
  form.variables.push({
    name: '',
    description: '',
    type: 'text'
  })
}

// 删除变量
const removeVariable = (index) => {
  form.variables.splice(index, 1)
}

// 插入变量
const insertVariable = (variable) => {
  const textarea = document.querySelector('.template-editor textarea')
  if (!textarea) return
  
  const start = textarea.selectionStart
  const end = textarea.selectionEnd
  const content = form.content
  form.content = content.substring(0, start) + `{{${variable.name}}}` + content.substring(end)
  
  // 更新光标位置
  nextTick(() => {
    textarea.focus()
    textarea.setSelectionRange(
      start + variable.name.length + 4,
      start + variable.name.length + 4
    )
  })
}

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return
  
  try {
    await formRef.value.validate()
    submitting.value = true
    
    if (dialogType.value === 'create') {
      await createMessageTemplate(form)
      ElMessage.success('创建成功')
    } else {
      await updateMessageTemplate(form)
      ElMessage.success('更新成功')
    }
    
    dialogVisible.value = false
    fetchTemplateList()
  } catch (error) {
    console.error('提交失败:', error)
    ElMessage.error(error.message || '提交失败')
  } finally {
    submitting.value = false
  }
}

// 处理导入
const handleImport = () => {
  importVisible.value = true
  importFile.value = null
}

// 处理导出
const handleExport = async () => {
  try {
    const res = await exportMessageTemplates()
    const blob = new Blob([res.data], {
      type: 'application/vnd.ms-excel'
    })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `通知模板_${new Date().toLocaleDateString()}.xlsx`
    link.click()
    window.URL.revokeObjectURL(url)
    ElMessage.success('导出成功')
  } catch (error) {
    console.error('导出失败:', error)
    ElMessage.error('导出失败')
  }
}

// 文件变化
const handleFileChange = (file) => {
  importFile.value = file.raw
}

// 确认导入
const confirmImport = async () => {
  if (!importFile.value) return
  
  importing.value = true
  try {
    await importMessageTemplates(importFile.value)
    ElMessage.success('导入成功')
    importVisible.value = false
    fetchTemplateList()
  } catch (error) {
    console.error('导入失败:', error)
    ElMessage.error('导入失败')
  } finally {
    importing.value = false
  }
}

// 工具函数
const getMessageTypeTag = (type) => {
  const typeMap = {
    system: 'info',
    notification: 'success',
    warning: 'warning',
    error: 'danger'
  }
  return typeMap[type] || ''
}

const getMessageTypeLabel = (type) => {
  const typeItem = messageTypes.value.find(t => t.value === type)
  return typeItem ? typeItem.label : type
}

const getChannelTagType = (channel) => {
  const typeMap = {
    inApp: '',
    email: 'success',
    sms: 'warning',
    wecom: 'info'
  }
  return typeMap[channel] || ''
}

const getChannelLabel = (channel) => {
  const labelMap = {
    inApp: '站内消息',
    email: '邮件通知',
    sms: '短信通知',
    wecom: '企业微信'
  }
  return labelMap[channel] || channel
}
</script>

<style lang="scss" scoped>
.notification-template {
  padding: 20px;

  .operation-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .left {
      display: flex;
      align-items: center;
    }

    .right {
      display: flex;
      align-items: center;
      gap: 16px;
    }
  }

  .channel-tag,
  .variable-tag {
    margin-right: 8px;
    margin-bottom: 4px;

    .info-icon {
      margin-left: 4px;
      font-size: 12px;
      cursor: help;
    }
  }

  .template-editor {
    .editor-toolbar {
      margin-bottom: 8px;
    }
  }

  .variables-editor {
    .variable-item {
      display: flex;
      align-items: center;
      gap: 8px;
      margin-bottom: 8px;
    }
  }

  .preview-content {
    .preview-header {
      margin-bottom: 20px;
      
      h3 {
        margin: 0 0 8px;
      }
    }

    .preview-body {
      .preview-variable {
        display: flex;
        align-items: center;
        margin-bottom: 16px;

        .variable-label {
          width: 100px;
          text-align: right;
          margin-right: 8px;
        }
      }

      .preview-result {
        margin-top: 20px;
        padding: 16px;
        background-color: #f5f7fa;
        border-radius: 4px;

        .result-label {
          margin-bottom: 8px;
          font-weight: bold;
        }

        .result-content {
          white-space: pre-wrap;
          word-break: break-all;
        }
      }
    }
  }

  .template-upload {
    :deep(.el-upload-dragger) {
      width: 100%;
    }
  }

  .pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
  }
}
</style> 